
#ifndef __TINY_LOGGER_HPP__
#define __TINY_LOGGER_HPP__

#include    <string>
#include    <map>

#include    "tiny/loglevel.hpp"
#include    "tiny/logappender.hpp"

namespace   tiny
{

class   Logger
{

private :
    Logger(const std::string& strCategory);

public  :
    ~Logger();
    
public  :

    static  void    configure(const char* pszConfigure = NULL);

    static  Logger* getInstance(const char* pszCategory="root");

public  :
    
    int     fatal(const char* pszFileName, int iLineNo, const char* pszFormat, ...);

    int     error(const char* pszFileName, int iLineNo, const char* pszFormat, ...);

    int     warn(const char* pszFileName, int iLineNo, const char* pszFormat, ...);

    int     info(const char* pszFileName, int iLineNo, const char* pszFormat, ... );

    int     debug(const char* pszFileName, int iLineNo, const char* pszFormat, ...);

    int     trace(const char* pszFileName, int iLineNo, const char* pszFormat, ...);

public  :
    typedef std::string appender_name_type;
    typedef std::map<appender_name_type, LogAppender*> appender_map_type;
    
    typedef int loglevel_type;
    typedef std::map<loglevel_type, appender_map_type>   loglevel_appenders_type;

private    :
    void    insertLogLevelAppender(loglevel_type, appender_name_type, LogAppender* );
    void    eraseLogLevelAppender(loglevel_type, appender_name_type );

private :

    int     append(appender_map_type& appenders, const char* pszFileName, int iLineNo, int iCategory, const char* pszMessage );

    const char* getTimeStampString();

    const std::string&  getCategory() const;

private :

    enum {
        SIZE_MESSAGE_BUF = 4096,
        SIZE_TIMESTAMP_BUF = 64,
    };

    static  const   std::string CATEGORY_ROOT;
    static  const   std::string CATEGORY_CONSOLE;

    typedef std::string category_name_type;
    typedef std::map<category_name_type, Logger*>  category_map_type;
    static  category_map_type    m_categories;

    static  appender_map_type   m_appenders;

private :
    loglevel_appenders_type  m_loglevel_appenders;

    char*   m_pszMessageBuf;
    char*   m_pszTimeStampBuf;

    const std::string m_strCategory;
};  // class Logger


Logger* getLogger(const char* pszCategory="root");


}   // namespace tiny

#endif  // __TINY_LOGGER_HPP__

